#ifndef _UART0_H
#define _UART0_H

#include <stdio.h>      
#include <stdlib.h>      
#include <unistd.h>      
#include <sys/types.h>   
#include <sys/stat.h>     
#include <fcntl.h>        
#include <termios.h>     
#include <errno.h>      
#include <string.h>  

int uart0_open(int fd,char *port){
	fd=open(port,O_RDWR|O_NOCTTY|O_NDELAY);
	if(!fd)return -1;
	if(fcntl(fd,F_SETFL,0)<0)return -1;
	if(!isatty(STDIN_FILENO))return -1;
	return fd;
}

int uart0_close(int fd){
	close(fd);
	return 0;
}

int uart0_set(int fd,int speed,int flow_ctrl,int databits,int stopbits,char parity){
	int i,status;
	int speed_arr[]={B115200,B19200,B9600,B4800,B1200,B300};
	int name_arr[]={115200,19200,9600,4800,2400,1200,300};
	struct termios options;
	if(tcgetattr(fd,&options)!=0)return -1;
	for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)  
                {  
                     if  (speed == name_arr[i])  
                            {               
                                 cfsetispeed(&options, speed_arr[i]);   
                                 cfsetospeed(&options, speed_arr[i]);    
                            }  
              }
	options.c_cflag|=CLOCAL;
	options.c_cflag|=CREAD;
	switch(flow_ctrl){
		case 0:
				options.c_cflag&=~CRTSCTS;  
				break;
		case 1:
				options.c_cflag|=CRTSCTS;
				break;
		case 2:
				options.c_cflag|=IXON|IXOFF|IXANY;
				break;
		default:
				return -1;
	}
	options,c_cflag&=~CSIZE;
	switch(databits){
		case 5:
				options.c_cflag|CS5;
				break;
		case 6:
				options.c_cflag|=CS6;
				break;
		case 7:
				options.c_cflag|=CS7;
				break;
		case 8:
				options.c_cflag|=CS8;
				break;		
		default:
				return -1;
	}
	switch(parity)
		case 'n':
		case 'N':
				options.c_cflag&=~PARENB;
				options.c_cflag&=~INPCK;
				break;
		case 'o':
		case 'O':
				options.c_cflag&=(PARODO|PARENB);
				options.c_cflag&=INPCK;
				break;
		case 'e':   
		case 'E':   
                 options.c_cflag|=PARENB;         
                 options.c_cflag&=~PARODD;         
                 options.c_iflag|=INPCK;        
                 break;  
		case 's':  
		case 'S':  
                 options.c_cflag&=~PARENB;  
                 options.c_cflag&=~CSTOPB;  
                 break;   		
		default:
				return -1;
	}
	switch (stopbits)  
    {    
       case 1:     
                 options.c_cflag &= ~CSTOPB; break;   
       case 2:     
                 options.c_cflag |= CSTOPB; break;  
       default:     
                       fprintf(stderr,"Unsupported stop bits\n");   
                       return (FALSE);  
    }  
     
	//修改输出模式，原始数据输出  
	options.c_oflag &= ~OPOST;  
	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);  
    //设置等待时间和最小接收字符  
    options.c_cc[VTIME] = 1; //读取一个字符等待1*(1/10)s     
    options.c_cc[VMIN] = 1; // 读取字符的最少个数为1  
    //如果发生数据溢出，接收数据，但是不再读取 刷新收到的数据但是不读  
    tcflush(fd,TCIFLUSH);       
    if (tcsetattr(fd,TCSANOW,&options) != 0)return -1;    
    return 0;   
}

int uart0_Init(int fd, int speed,int flow_ctrl,int databits,int stopbits,char parity)  
{    
    if (UART0_Set(fd,speed,flow_ctrl,databits,stopbits,parity)!=0)  return -1;
	return 0;
} 

int uart0_Recv(int fd, char *rcv_buf,int data_len)  
{  
    int len,fs_sel;  
    fd_set fs_read;  
     
    struct timeval time;  
     
    FD_ZERO(&fs_read);  
    FD_SET(fd,&fs_read);  
     
    time.tv_sec = 10;  
    time.tv_usec = 0;  
    fs_sel = select(fd+1,&fs_read,NULL,NULL,&time);  
    if(!fs_sel)return -1;  
	len = read(fd,rcv_buf,data_len);
    return len;  
}  

int uart0_Send(int fd, char *send_buf,int data_len)  
{  
    int len = 0;  
     
    len = write(fd,send_buf,data_len);  
    if (len == data_len ) return len;     
    else{
		tcflush(fd,TCOFLUSH);  
        return -1;  
	} 
}  